<template>
  <el-dialog class="public-dialog" title="自定义费用导入" :modelValue="modelValue" align-center width="90%" height="90vh" @close="handleClose" :close-on-click-modal="false">
    <div class="flex" style="flex-direction: column">
      <XForm ref="formRef" :fieldList="fieldList" :options="formOption" :formData="formData" :originOption="originOption" :rules="rules" />
      <div class="flex mb-[16px]">
        <div class="w-[220px] flex">
          <div class="w-[120px] text-right flex-1">导入文件：</div>
          <div class="">
            <el-steps direction="vertical" class="steps" active="0">
              <el-step title="准备导入内容">
                <template #description><el-button class="ml-[20px]" size="small" @click="handleDownload" :disabled="formOption.disabled"> 下载模板 </el-button></template>
              </el-step>
              <el-step title="上传导入文件">
                <template #description>
                  <el-upload class="ml-[20px]" action accept=".xlsx,xls" :auto-upload="false" :show-file-list="false" :on-change="handleChange">
                    <el-button size="small" type="primary" :disabled="formOption.disabled" :loading="loadings.upload"> 上传文件 </el-button>
                  </el-upload>
                </template>
              </el-step>
            </el-steps>
          </div>
        </div>
        <div class="flex px-[6px] flex-1">
          <div class="w-[100px] text-right">注意事项：</div>
          <div class="flex-1" v-if="formData.import_mode == 1">
            <div>1.以文件形式导入或直接在表格中编辑，一行一条记录，* 为必填项</div>
            <div>2.一个订单多笔金额，会汇总后导入</div>
            <div>3.金额：“正数”代表收入，“负数”代表支出</div>
          </div>
          <div class="flex-1" v-else>
            <div>1.以文件形式导入或直接在表格中编辑，一行一条记录，* 为必填项</div>
            <div>2.店铺取系统上记录的店铺名称，区分大小写</div>
            <div>3.金额：“正数”代表收入，“负数”代表支出</div>
            <div>4.销售人员取系统上记录的名称，不包含中文，同店铺多个销售人员需线下分摊好，再录入</div>
            <div>5.结算时间格式：2024/5/20 14:28:36</div>
          </div>
        </div>
      </div>
    </div>

    <div class="flex-1">
      <div class="flex px-[6px]">
        <div class="w-[100px] text-right title">导入内容：</div>
        <div class="flex-1">
          <vxe-grid ref="tableRef" v-bind="tableOptions" class="log-table" :loading="loadings.submit">
            <template #requiredHeader="{ column }">
              <span class="title">
                {{ column.title }}
              </span>
            </template>
            <!-- 系统订单号 -->
            <template #orderSn="{ row }">
              <el-input v-model.trim="row.order_sn" />
            </template>

            <!-- 金额 -->
            <template #originalAmount="{ row }">
              <el-input v-model.trim="row.original_amount" />
            </template>

            <!-- 店铺 -->
            <template #shopSlot="{ row }">
              <!-- {{ row.shop }} -->
              <el-select-v2 v-model="row.shop" :options="shopOpt" style="width: 100%" filterable clearable @change="valueGetLabel($event, row, 'shop')" />
            </template>
            <!-- 销售人员 -->
            <template #userSlot="{ row }">
              <el-cascader
                v-model="row.salesperson"
                :show-all-levels="false"
                :options="userOpt"
                filterable
                :props="{ emit: false, emitPath: false, multiple: false, label: 'name', value: 'id', children: 'sub' }"
                style="width: 100%"
                @change="valueGetLabel($event, row, 'salesperson')"
                teleported
              />
            </template>

            <!-- 金额 -->
            <template #Time="{ row }">
              <el-date-picker v-model="row.original_settlement_at" type="datetime" class="w-[100%]" value-format="YYYY/MM/DD HH:mm:ss" />
            </template>

            <!-- sku -->
            <template #SKU="{ row, column }">
              <el-input v-model.trim="row[column.field]" />
            </template>
          </vxe-grid>
          <el-button type="primary" class="w-[100%]" @click="addRow" v-if="!formOption.disabled">添加行 </el-button>
        </div>
      </div>

      <div class="flex items-center px-[6px] flex-1 mt-[6px]" v-if="tableOptions.data.find((v) => v.id)">
        <div class="w-[100px] text-right">导入结果：</div>
        <div class="flex-1">
          <span class="text-green text-[20px]"> 成功： {{ tableOptions.data.filter((v) => v.result == 1).length }}条， </span>
          <span class="text-red text-[20px]"> 失败： {{ tableOptions.data.filter((v) => v.result == 0).length }}条 </span>
        </div>
      </div>
    </div>

    <template #footer>
      <el-button @click="handleClose(false)">取消</el-button>
      <el-button type="primary" @click="handleUpload" v-if="!formOption.disabled" :loading="loadings.submit"> 导入 </el-button>
    </template>
  </el-dialog>
</template>

<script setup lang="jsx">
import { ElMessage, ElMessageBox } from "element-plus"
import { uploadSignUrl } from "@/api/public"

import { downloadTemplate, expenseCustomImport, downloadFrameTemplate, expenseItem, expenseImport, expenseImportDetail } from "../../api"
import { getShop } from "@/api/public"
const handleColumn = {
  title: "操作",
  width: 150,
  fixed: "right",
  slots: {
    default: ({ row, rowIndex }) => {
      return [
        <div class="flex flex-wrap">
          <el-button link type="danger" onClick={() => delRow(rowIndex)}>
            删除
          </el-button>
        </div>,
      ]
    },
  },
}

const valueGetLabel = (e, item, key) => {
  if (key == "shop") {
    item.shopShow = shopOpt.value.find((v) => e == v.value)?.label
  }
  if (key == "salesperson") {
    item.salespersonShow = userOptObjKey.value[e]
  }
}
const delRow = (index) => {
  // console.log(index)
  tableOptions.data.splice(index, 1)
}
const addRow = () => {
  tableOptions.data.push({})
}

const props = defineProps({})
let tableColumns = {
  1: [
    {
      field: "order_sn",
      title: "系统订单号",
      width: 200,
      editRender: { props: { placeholder: "请输入" } },
      // slots: { edit: "orderSn" },
      slots: { header: "requiredHeader", edit: "orderSn" },
    },
    {
      field: "original_amount",
      title: "金额",
      width: 200,
      editRender: { props: { placeholder: "请输入" } },
      slots: { header: "requiredHeader", edit: "originalAmount" },
    },
    { field: "failed_reason", title: "导入结果" },
  ],
  2: [
    {
      field: "shopShow",
      title: "店铺",
      width: 200,
      editRender: { props: { placeholder: "请输入" } },
      slots: { edit: "shopSlot", header: "requiredHeader" },
    },
    {
      field: "original_amount",
      title: "金额",
      width: 100,
      editRender: { props: { placeholder: "请输入" } },
      slots: { header: "requiredHeader", edit: "originalAmount" },
    },
    {
      field: "salespersonShow",
      title: "销售人员",
      width: 180,
      editRender: { props: { placeholder: "请输入" } },
      // slots: { default: "userSlot", edit: "userSlot" },
      slots: { edit: "userSlot", header: "requiredHeader" },
      // editRender: "userSlot",
    },
    {
      field: "original_settlement_at",
      title: "结算时间",
      width: 180,
      // name: "ElInput",
      editRender: { props: { placeholder: "请输入" } },
      slots: { edit: "Time" },
    },

    {
      field: "sku",
      title: "系统SKU",
      width: 120,
      editRender: { props: { placeholder: "请输入" } },
      slots: { edit: "SKU" },
    },
    {
      field: "platform_sku",
      title: "渠道SKU",
      width: 120,
      editRender: { props: { placeholder: "请输入" } },
      slots: { edit: "SKU" },
    },
    {
      field: "order_sn",
      title: "系统订单号",
      width: 120,
      editRender: { props: { placeholder: "请输入" } },
      slots: { edit: "SKU" },
    },

    { field: "failed_reason", title: "导入结果" },
  ],
}

// 列表行 样式
const rowStyle = ({ row, rowIndex }) => {
  if (row?.result == 0) return { color: "red" }
}

const editRules = {
  order_sn: [{ required: true }],
  original_amount: [{ required: true, message: "请输入" }],
  shopShow: [{ required: true, message: "请输入" }],
  salespersonShow: [{ required: true, message: "请输入" }],
  original_settlement_at: [{ required: true, message: "请输入" }],
}

const tableOptions = reactive({
  height: "400px",
  border: "full",
  rowStyle: rowStyle,
  scrollY: { enabled: false },
  editConfig: { trigger: "click", mode: "row", showStatus: true },
  // editRules: {
  //   // order_sn: [{ required: true, message: "请输入" }],
  //   // original_amount: [{ required: true, message: "请输入" }],
  //   // shopShow: [{ required: true, message: "请输入" }],
  //   // salespersonShow: [{ required: true, message: "请输入" }],
  //   // original_settlement_at: [{ required: true, message: "请输入" }],
  // },
  columns: [],
  data: [],
})

import XForm from "@/components/XForm/index.vue"
const formOption = ref({ inline: true, labelWidth: "100px" })
const formData = ref({ import_mode: 1, import_type: 1, currency: "CNY" })
const fieldList = ref([
  {
    label: "导入方式",
    field: "import_mode",
    type: "select",
    clearable: false,
    options: {
      data: [
        { label: "按订单导入", value: 1 },
        { label: "按店铺导入", value: 2 },
      ],
      placeholder: "导入方式",
    },
    style: { width: "200px" },
    change: (e) => {
      tableOptions.data = [{}]
      initTable()
      if (e == 2) {
        formData.value.import_type = 1
      }
      fieldList.value?.forEach((v) => {
        v.field == "import_type" && (v.disabled = e == 2)
      })
    },
  },
  {
    label: "费用项",
    field: "expense_item",
    type: "select",
    originField: "expense_item",
    style: { width: "320px" },
    change: (e, form) => {
      if (form.import_mode == 2) {
        let columns = tableColumns[form.import_mode]
        columns.forEach((item) => {
          if (["sku", "platform_sku", "order_sn"].includes(item.field)) {
            item.slots = { edit: "SKU" }
            if (originOption.value.expense_item.find((v) => v.value == e)?.label == "异形费" && item.field == "order_sn") {
              item.slots.header = "requiredHeader"
            }
            if (originOption.value.expense_item.find((v) => v.value == e)?.label == "无API对接的广告费" && item.field == "platform_sku") {
              item.slots.header = "requiredHeader"
            }
          }
        })
        tableRef?.value?.loadColumn([...columns, handleColumn])
      }
    },
  },
  {
    label: "导入类型",
    field: "import_type",
    type: "select",
    options: {
      data: [
        { label: "新增", value: 1 },
        { label: "累加", value: 2 },
        { label: "替换", value: 3 },
      ],
      placeholder: "导入类型",
    },
    // slot:"aaaaa",
    tooltip: `<div>
      <div>1.“新增”：可对订单新增一笔所选费用项的金额</div>
      <div class='ml-[16px]'>1.1如果导入的数据中一个订单存在多笔金额时，系统会自动汇总导入金额</div>
      <div class='ml-[16px]'>1.1如果订单中已导入过此费用项，则不可再新增，可通过“累加”或“替换”重新导入费用</div>
      <div>2.“替换”：会替换对应订单中当前费用项已导入的金额</div>
      <div class='ml-[16px]'>2.1如果导入的数据中一个订单存在多笔金额时，系统会自动汇总导入金额</div>
      <div class='ml-[16px]'>2.2如当前订单没有导入过所选择的费用项，则会自动新增导入费用</div>
      <div>3.“累加”：会将导入金额累加到对应订单当前的费用项中</div>
      <div class='ml-[16px]'>3.1如果导入的数据中一个订单存在多笔金额时，系统会自动汇总导入金额</div>
      <div class='ml-[16px]'>3.2如当前订单没有导入过所选择的费用项，则会自动新增导入费用</div>
    </div>`,
    style: { width: "200px" },
    disabled: false,
  },
  { label: "币种", field: "currency", type: "select", originField: "countryOpt", style: { width: "200px" } },
  { label: "导入备注", field: "remark", type: "textarea", full: true, style: { width: "630px" }, autosize: { minRows: 1, maxRows: 2 } },
])

const rules = reactive({
  import_mode: [{ required: true, message: "请选择导入方式", trigger: "change" }],
  expense_item: [{ required: true, message: "请选择费用项", trigger: "change" }],
  import_type: [{ required: true, message: "请选择导入类型", trigger: "change" }],
  currency: [{ required: true, message: "请选择币种", trigger: "change" }],
  remark: [{ required: true, message: "请输入", trigger: "blur" }],
})

const modelValue = ref(false)
let ossParams = reactive({
  host: "",
})
const extraData = reactive({})
const uploadPercent = ref(0)

let loadings = reactive({})

const emit = defineEmits(["refresh"])

const fileList = ref([])
const fileName = ref("")
const upload = ref()
const shopOpt = ref({})
const userOpt = ref({})
const shopOptObj = ref({})

const userOptObj = ref({})
const userOptObjKey = ref({})

import cache from "@/plugins/cache"

onMounted(() => {
  initUpload()
  getShop().then((res) => {
    shopOpt.value = res.data.map((v) => ({ value: v.shop_id, label: v.shop_name }))
    shopOptObj.value = Object.fromEntries(shopOpt.value.map((v) => [v.label.toLowerCase(), v.value]))
  })
  let personnelOptions = cache.session.getJSON("personnel") || ""
  userOpt.value = personnelOptions
  userOptObj.value = getUser(personnelOptions)
  userOptObjKey.value = Object.fromEntries(Object.entries(userOptObj.value).map((v) => [v[1], v[0]]))
})
const getUser = (list) => {
  let user = {}
  let fn = (data) => {
    data?.forEach((item) => {
      if (item?.sub?.length) {
        fn(item.sub)
      } else {
        item.name = item.name.trim()
        user[item.name.toLowerCase()] = item.user_id
      }
    })
  }
  fn(list)
  return user
}
const frameTemplate = ref({})
import { getCurrency, apiGetWarehouseEnum, goodsBaseGetEnums } from "@/api/public"
const originOption = ref({})
const initUpload = async () => {
  frameTemplate.value = (await downloadFrameTemplate())?.data?.template_url
  originOption.value.countryOpt = (await getCurrency()).data.map((v) => ({ label: v.label, value: v.label }))

  originOption.value.expense_item = (await expenseItem()).data.map((v) => ({ label: v.name, value: v.id }))
}
// 下载模版
const handleDownload = async () => {
  // console.log(frameTemplate.value)
  let url = formData.value.import_mode == "1" ? frameTemplate.value.order : frameTemplate.value.shop
  window.open(url, "noopener", "noreferrer")
}

const handleExceed = (files) => {
  upload.value?.clearFiles()
  const file = files[0]
  upload.value?.handleStart(file)
}

const get_suffix = (name) => {
  const pos = name.lastIndexOf(".")
  let suffix = ""
  if (pos != -1) {
    suffix = name.substring(pos)
  }
  return suffix
}
const formRef = ref()
const handleChange = async (ev) => {
  try {
    let file = ev.raw
    if (!file) {
      return ElMessage({ message: "请选择文件！", type: "warning" })
    }
    readFile(file)
  } catch (error) {}
}
const uploadLoading = ref(false)
import XLSX from "xlsx"

import { parseTime } from "@/utils/ruoyi"
const xlsxConfig = {
  "店铺（*必填）": "shop",
  "金额（*必填）": "original_amount",
  "销售人员（*必填）": "salesperson",
  结算时间: "original_settlement_at",
  "系统订单号（*必填）": "order_sn",
  "金额（*必填）": "original_amount",
  系统SKU: "sku",
  渠道SKU: "platform_sku",
  系统订单号: "order_sn",
}
const handleUpload = async () => {
  loadings.submit = true
  try {
    let tableValidateIndex = null
    if (formData.value.import_mode == 1) {
      tableValidateIndex = tableOptions.data.findIndex((v) => !v.order_sn || !v.original_amount)
    } else {
      tableValidateIndex = tableOptions.data.findIndex((v) => !v.shop || !v.original_amount || !v.salesperson)
      if (tableValidateIndex == -1) {
        // if (originOption.value.expense_item.find((v) => v.value == e)?.label == "异形费" && item.field == "order_sn") {
        //   item.slots.header = "requiredHeader"
        // }
        // if (originOption.value.expense_item.find((v) => v.value == e)?.label == "无API对接的广告费" && item.field == "platform_sku") {
        //   item.slots.header = "requiredHeader"
        // }

        if (formData.value.import_mode == 2 && originOption.value.expense_item.find((v) => v.value == formData.value.expense_item)?.label == "异形费") {
          tableValidateIndex = tableOptions.data.findIndex((v) => !v.order_sn)
        }
        if (formData.value.import_mode == 2 && originOption.value.expense_item.find((v) => v.value == formData.value.expense_item)?.label == "无API对接的广告费") {
          tableValidateIndex = tableOptions.data.findIndex((v) => !v.platform_sku)
        }
      }
    }
    if (tableValidateIndex != -1) {
      loadings.submit = false
      return ElMessage({ message: `第${tableValidateIndex}行数据有误！`, type: "warning" })
    }

    if (formData.value.import_mode == 2) {
      tableOptions.data?.forEach((item) => {
        item.shop_id = JSON.parse(JSON.stringify(item.shop))
        item.shop = item.shopShow
        item.sales_id = [item.salesperson]
      })
    }

    // console.log(tableOptions.data)
    await formRef.value?.submit()
    let params = {
      ...formData.value,
      details: tableOptions.data,
    }

    let res = await expenseImport(params)

    let rps = await expenseImportDetail(res.data.import_id)

    formData.value.id = res.data.import_id
    tableOptions.data = rps?.data?.details
    if (formData.value.import_mode == 2) {
      tableOptions.data?.forEach((item) => {
        item.shop = item.shop_id
        valueGetLabel(item.shop_id, item, "shop")
        item.salespersonShow = item.salesperson
        item.salesperson = userOptObj.value[item.salesperson.toLowerCase()]
      })
    }

    if (rps?.data?.details.filter((v) => v.result == 0).length == 0) {
      handleClose()
      nextTick(() => {
        ElMessageBox.alert("费用导入成功，<br/>审核通过后系统自动计算利润!", "注意事项", {
          confirmButtonText: "确认",
          dangerouslyUseHTMLString: true,
        })
      })
    }
    loadings.submit = false
  } catch (error) {
    loadings.submit = false
  }
}

// 读取文件
const readFile = (file) => {
  loadings.upload = true
  try {
    let reader = new FileReader()
    reader.readAsBinaryString(file)
    reader.onload = (ev) => {
      let data = ev.target.result
      let workbook = XLSX.read(data, { type: "binary", cellDates: true })
      const wsname = workbook.SheetNames[0] //取第一张表
      const ws = XLSX.utils.sheet_to_json(workbook.Sheets[wsname])
      // console.log("ws", ws)
      // console.log("file", file)
      // 判断文件模板
      if (ws.length == 0) {
        loadings.upload = false
        return ElMessage({ message: "文件不包含任何内容", type: "warning" })
      }
      let keyArr = Object.keys(ws[0])
      // 填充表格
      let details = []
      // console.log(ws)
      ws.map(async (item, index) => {
        let obj = {}
        for (let key in item) {
          obj[xlsxConfig[key]] = String(item[key]).trim()
          if (key == "结算时间") {
            obj[xlsxConfig[key]] = parseTime(Math.floor(new Date(obj[xlsxConfig[key]]).getTime() / 1000) + 50, "{y}/{m}/{d} {h}:{i}") + ":00"
          }
        }
        details.push(obj)
      })

      if (formData.value.import_mode == 2) {
        details?.forEach((item) => {
          item.shopShow = item.shop
          item.shop = shopOptObj.value[item?.shop?.toLowerCase()]
          item.salespersonShow = item.salesperson
          item.salesperson = userOptObj.value[item?.salesperson?.toLowerCase()]
        })
      }

      initTable()
      tableOptions.data = details
      loadings.upload = false
    }
    reader.onerror = () => {
      ElMessage({ message: "读取失败，请重新选择文件再上传", type: "error" })
      loadings.upload = false
    }
  } catch (e) {
    ElMessage({ message: "e", type: "error" })
    loadings.upload = false
  }
}
const tableRef = ref()
const initTable = () => {
  if (formOption.value.disabled) {
    tableRef?.value?.loadColumn(tableColumns[formData.value.import_mode])
  } else {
    tableRef?.value?.loadColumn([...tableColumns[formData.value.import_mode], handleColumn])
  }
}
const beforeUpload = async (file) => {
  if (file.size > 1024 * 1024 * 1024) {
    ElMessage.warning("上传视频大小不能超过1G")
    return false
  }
  await initUpload()
  uploadPercent.value = 0
  try {
    const { policy, accessid, dir, signature, callback } = ossParams || {}
    // console.warn(file)
    const name = `${file.name.split(".")[0]}${+new Date()}`
    const _fileName = name + get_suffix(file.name)
    extraData.key = dir + _fileName

    extraData.policy = policy
    extraData.OSSAccessKeyId = accessid
    extraData.signature = signature
    fileName.value = _fileName
    return true
  } catch (err) {
    fileName.value = ""
    // console.log(err)
    ElMessage.error(err.message)
    return false
  }
}

const handleUploadProgress = (e) => {
  uploadPercent.value = parseInt(e.percent)
}

const handleUploadError = (err) => {
  fileName.value = ""
  ElMessage.error(`上传失败 ${err.toString()}`)
  uploadPercent.value = 0
}

const handleUploadSuccess = (res, file, fileList) => {
  ElMessage.success("上传成功")
}

const handleClose = (refresh) => {
  modelValue.value = false
  if (tableOptions.data.find((v) => v.result == 1)) emit("refresh")
  formData.value = { import_mode: 1, import_type: 1, currency: "CNY" }
  tableOptions.data = []
}

const submit = async () => {
  loadings.submit = true
  try {
    if (!fileName.value) {
      ElMessage.warning("请检查文件是否上传")
      return
    }
    await expenseCustomImport({
      file_name: fileName.value,
      file_path: `${ossParams.dir}${fileName.value}`,
      remark: remark.value || undefined,
    })
    handleClose(true)
  } catch (e) {
    console.error(e)
  } finally {
    loadings.submit = false
  }
}

const open = async (row, type) => {
  modelValue.value = true
  formOption.value.disabled = type == "look"
  tableOptions.editConfig.enabled = type != "look"

  if (row.id) {
    let rps = await expenseImportDetail(row.id)
    formData.value = rps.data
    initTable()
    tableOptions.data = rps?.data?.details
    tableOptions.data?.forEach((item) => {
      item.shopShow = item.shop
      item.shop = shopOptObj.value[item.shop.toLowerCase()]
      item.salespersonShow = item.salesperson
      item.salesperson = item.sales_id[0]
    })
  } else {
    tableOptions.data = [{}]
  }
  fieldList.value?.forEach((v) => {
    v.field == "import_type" && (v.disabled = formData.value.import_mode == 2)
  })

  setTimeout(() => {
    initTable()
  }, 500)
}
defineExpose({
  open,
})
</script>

<style lang="scss" scoped>
.v-import {
  :deep(.el-upload-dragger) {
    padding: 12px;
    display: flex;
    align-items: center;
    justify-content: center;
    border-color: #3366f1;
  }
}
:deep(.steps) {
  .el-step__head {
    color: #a8abb2;
  }
  .el-step__title {
    font-size: 12px;
    color: #a8abb2;
  }
}
.title::before {
  content: "*";
  color: #f56c6c;
  margin-right: 4px;
}
.log-table {
  z-index: 9;
  width: 100%;
}
</style>
